package tuling.EalyAopDemo.chaindemo;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import tuling.EalyAopDemo.TulingLogAdvice;
import tuling.EalyAopDemo.TulingLogInterceptor;
import tuling.TulingCalculate;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class MainStart {

	public static void main(String[] args) throws Throwable {

		List<MethodInterceptor> list = new ArrayList<>();
		list.add(new MethodBeforeAdviceInterceptor(new TulingLogAdvice()));
		list.add(new TulingLogInterceptor());

		MyMethodInvocation methodInvocation = new MyMethodInvocation(list);
		methodInvocation.proceed();

	}

	public static class MyMethodInvocation implements MethodInvocation {
		private List<MethodInterceptor> list;
		private TulingCalculate target;
		private int i = 0;

		public MyMethodInvocation(List<MethodInterceptor> list) {
			this.list = list;
			this.target = new TulingCalculate();
		}

		@Override
		public Object proceed() throws Throwable {
			if (i == list.size()) {
				return target.add(8, 8);
			}
			MethodInterceptor methodInterceptor = list.get(i);
			i++;

			return methodInterceptor.invoke(this);
		}

		@Override
		public Object getThis() {
			return target;
		}

		@Override
		public AccessibleObject getStaticPart() {
			return null;
		}

		@Override
		public Method getMethod() {
			try {
				return target.getClass().getMethod("add", int.class, int.class);
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override
		public Object[] getArguments() {
			return new Object[0];
		}
	}
}
